﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using ZRFCore.MotionControlCard;
using ZRFCore.MotionControlCard.Zmc;
using ZRFCore.Tool;

namespace MultiAxisAssembly.Motion
{
    public class Machine
    {
        protected IMotion motion;//运动卡对象
        /// <summary>
        /// 初始化完成
        /// </summary>
        public bool IsInitialized { get; private set; }
        public bool IsRunMark { get { return isRunMark; } }
        protected bool isRunMark = false;//正在回零标记

        protected bool isAllHomed = false;
        private readonly string ethercatIp = "192.168.0.11";

        public MotionStatus MotionStatus
        {
            get
            {
                return motion.MotionStatus;
            }
        }

        public Machine()
        {
            motion = new ZmcMotion();
            IsInitialized = false;
        }

        /// <summary>
        /// 初始化
        /// </summary>
        /// <returns>返回初始化的结果  true：初始化成功</returns>
        public void Init()
        {
            try
            {
                Log.LogSysMsg("运动卡连接..ip:" + ethercatIp);
                //运动卡连接
                motion.ConnectEtherCat(ethercatIp);
                Log.LogSysMsg("运动卡连接成功");
                //IO初始化
                motion.InitAllIO(36, 12);
                //轴初始化
                motion.InitAllAxis(new AxisInitType[]{
                                                        new AxisInitType(){AxisIndex = 0,AxisType = AxisType.StepperMotor,Brand = new  Brand_LeadShine()},
                                                         new AxisInitType(){AxisIndex = 1,AxisType = AxisType.StepperMotor,Brand = new  Brand_LeadShine()},
                                                          new AxisInitType(){AxisIndex = 2,AxisType = AxisType.StepperMotor,Brand = new  Brand_LeadShine()},
                                                     });//XYZ

                //插补初始化
                motion.InitAllInterpolation(new List<int[]> { new int[] { 0, 1, 2, } });

                //foreach (var output in motion.Outputs)
                //{
                //    output.IsGlobalControl = false;
                //}


                //默认设置
                XAxis.Invert = true;
                YAxis.Invert = true;
                ZAxis.Invert = false;

                XAxis.Input_Origin = 0;
                YAxis.Input_Origin = 1;
                ZAxis.Input_Origin = 2;

                //软限位
                XAxis.SoftPositiveLimit = 305;
                XAxis.SoftNegativeLimit = 0;

                YAxis.SoftPositiveLimit = 310;
                YAxis.SoftNegativeLimit = 0;

                ZAxis.SoftPositiveLimit = 93;
                ZAxis.SoftNegativeLimit = 0;

                //脉冲当量设置 （每单位脉冲数）
                XAxis.Units = 106;
                YAxis.Units = 106;
                ZAxis.Units = 106;

                //复位爬行速度
                XAxis.HomingCreep = 10;
                YAxis.HomingCreep = 10;
                ZAxis.HomingCreep = 10;
                //最大速度(按设置过当量计算)
                MaxSpeed = 200;
                Speed = 100;

                Interpolation.DecelAngle = 15;
                Interpolation.StopAngle = 30;

                Out_SpurtGlueControl.PausedStatus = PausedStatus.False;
                Out_PointGlueControl.PausedStatus = PausedStatus.False;

                IsInitialized = true;
                Log.LogSysMsg("运动卡初始化完成.");
            }
            catch (Exception e)
            {
                throw new Exception(e.Message);
            }
        }

        #region IO
        //输入
        public IInput[] Inputs { get { try { return motion.Inputs; } catch { throw new Exception("未初始化或初始化数量不对！"); } } }

        public IInput In_OutStartSignal { get { try { return motion.Inputs[17]; } catch { throw new Exception("未初始化或初始化数量不对！"); } } }//外部启动信号

        public IInput In_StartPauseButton { get { try { return motion.Inputs[18]; } catch { throw new Exception("未初始化或初始化数量不对！"); } } }//开始/暂停按钮

        public IInput In_ResetButton { get { try { return motion.Inputs[19]; } catch { throw new Exception("未初始化或初始化数量不对！"); } } }//复位按钮

        public IInput In_EmergentStopButton { get { try { return motion.Inputs[20]; } catch { throw new Exception("未初始化或初始化数量不对！"); } } }//急停按钮

        public IInput In_ManualButton { get { try { return motion.Inputs[21]; } catch { throw new Exception("未初始化或初始化数量不对！"); } } }//手动按钮

        //输出
        public IOutput[] Outputs { get { try { return motion.Outputs; } catch { throw new Exception("未初始化或初始化数量不对！"); } } }

        public IOutput Out_SpurtGlueControl { get { try { return motion.Outputs[0]; } catch { throw new Exception("未初始化或初始化数量不对！"); } } }//喷胶输出

        public IOutput Out_PointGlueControl { get { try { return motion.Outputs[1]; } catch { throw new Exception("未初始化或初始化数量不对！"); } } }//点胶输出

        public IOutput Out_GlueFinish { get { try { return motion.Outputs[10]; } catch { throw new Exception("未初始化或初始化数量不对！"); } } }//出胶完成信号

        public IOutput Out_GlueChangeToSpurt { get { try { return motion.Outputs[2]; } catch { throw new Exception("未初始化或初始化数量不对！"); } } }//切换成喷胶

        public IOutput Out_GlueChangeToSmall { get { try { return motion.Outputs[3]; } catch { throw new Exception("未初始化或初始化数量不对！"); } } }//切换成小胶头点胶
        #endregion

        #region 轴

        public IAxis XAxis { get { try { return motion.Axises[0]; } catch { throw new Exception("未初始化或初始化数量不对！"); } } }
        public IAxis YAxis { get { try { return motion.Axises[1]; } catch { throw new Exception("未初始化或初始化数量不对！"); } } }
        public IAxis ZAxis { get { try { return motion.Axises[2]; } catch { throw new Exception("未初始化或初始化数量不对！"); } } }

        /// <summary>
        /// 速度百分比。value = 50 ，即50%
        /// </summary>
        public float SpeedPercent
        {
            get
            {
                return Speed / MaxSpeed * 100;
            }
            set
            {
                if (value > 100)
                {
                    value = 100;
                }
                if (value < 0)
                {
                    value = 1;
                }
                Speed = (float)MaxSpeed * value / 100;
                Accel = (float)MaxSpeed * value / 10;
                Decel = (float)MaxSpeed * value / 10;
            }
        }

        public float MaxSpeed { get; set; }

        public float Speed
        {
            get
            {
                return XAxis.Speed;
            }
            set
            {
                if (value > MaxSpeed)
                {
                    XAxis.Speed = MaxSpeed;
                    YAxis.Speed = MaxSpeed;
                    ZAxis.Speed = MaxSpeed;
                }
                else
                {
                    XAxis.Speed = value;
                    YAxis.Speed = value;
                    ZAxis.Speed = value;
                }
            }
        }

        public float Accel
        {
            get
            {
                return XAxis.Accel;
            }
            set
            {
                XAxis.Accel = value;
                YAxis.Accel = value;
                ZAxis.Accel = value;
            }
        }

        public float Decel
        {
            get
            {
                return XAxis.Decel;
            }
            set
            {
                XAxis.Decel = value;
                YAxis.Decel = value;
                ZAxis.Decel = value;
            }
        }

        public void AllAxisesHoming()
        {
            if (isRunMark == true || this.MotionStatus.IsEmergentStop == true)
            {
                isRunMark = false;
                return;
            }
            isRunMark = true;
            Speed = MaxSpeed / 4;
            Accel = MaxSpeed;
            Decel = MaxSpeed * 5;
            ZAxis.Homing();
            while (ZAxis.HomeStatus != AxisHomeStatus.Homed)//等待Z轴复位完成
            {
                Thread.Sleep(1);
                if (ZAxis.HomeStatus == AxisHomeStatus.HomeErr)
                {
                    //Log.LogErrorMsg("Z轴回零异常。");
                    //allHomingMark = false;
                    //return;
                }
            }
            //rAxis.AxisHoming();
            //while (rAxis.HomeStatus != AxisHomeStatus.Homed)//等待r轴复位完成
            //{
            //    Thread.Sleep(1);
            //    if (rAxis.HomeStatus == AxisHomeStatus.HomeErr)
            //    {
            //        //Log.LogErrorMsg("R轴回零异常。");
            //        //allHomingMark = false;
            //        //return;
            //    }
            //}
            XAxis.Homing();
            YAxis.Homing();
            while (XAxis.HomeStatus != AxisHomeStatus.Homed)//等待x轴复位完成
            {
                Thread.Sleep(1);
                if (XAxis.HomeStatus == AxisHomeStatus.HomeErr)
                {
                    //Log.LogErrorMsg("R轴回零异常。");
                    //allHomingMark = false;
                    //return;
                }
            }
            while (YAxis.HomeStatus != AxisHomeStatus.Homed)//等待y轴复位完成
            {
                Thread.Sleep(1);
                if (YAxis.HomeStatus == AxisHomeStatus.HomeErr)
                {
                    //Log.LogErrorMsg("R轴回零异常。");
                    //allHomingMark = false;
                    //return;
                }
            }
            isAllHomed = true;
            isRunMark = false;
        }

        #endregion

        #region 插补
        /// <summary>
        /// 插补对象
        /// </summary>
        public IInterpolation Interpolation { get { try { return motion.Interpolationes[0]; } catch { throw new Exception("未初始化或初始化数量不对！"); } } }

        #endregion

        public void EmergentStop()
        {
            isRunMark = false;
            motion.EmergentStop();
        }

        public void ResetEmergentStop()
        {
            motion.ResetEmergentStop();
        }

        public void Pause()
        {
            motion.Pause();
        }

        public void Resume()
        {
            motion.Resume();
        }

        public void Reset()
        {
            foreach (var output in motion.Outputs)
            {
                output.Reset();
            }
            AllAxisesHoming();
        }

        public void Close()
        {
            motion.Close();
        }
    }
}
